﻿#include "GameScene.h"
#include "GameManager.h"
#include "ShareLayer.h"
USING_NS_CC;

#define  OPT_NUM 8

float optionShowdelay = 0.1; //0.5 todo change it

CCScene* GameScene::scene(int l)
{
	// 'scene' is an autorelease object
	CCScene *scene = CCScene::create();

	// 'layer' is an autorelease object
	GameScene *layer = GameScene::create();
	layer->level = l;
	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

bool GameScene::init()
{
	if ( !CCLayer::init() )
	{
		return false;
	}
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);

	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
	CCSprite *bg = CCSprite::create("background.png");
	bg->setPosition(ccp(visibleSize.width/2, visibleSize.height/2));
	addChild(bg);

	rightBorderSp = CCSprite::createWithSpriteFrameName("border.png");
	rightBorderSp->setPosition(ccp(-500, -500));
	addChild(rightBorderSp);
	wrongBorderSp = CCSprite::createWithSpriteFrameName("border.png");
	wrongBorderSp->setPosition(ccp(-500, -500));
	addChild(wrongBorderSp);

	CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
		"CloseNormal.png",
		"CloseSelected.png",
		this,
		menu_selector(GameScene::returnMainMenu));

	pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
		origin.y + pCloseItem->getContentSize().height/2));

	// create menu, it's an autorelease object
	CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
	pMenu->setPosition(CCPointZero);
	this->addChild(pMenu, 1);

	return true;
}

void GameScene::onEnter()
{
	CCLayer::onEnter();
	CCUserDefault *ud = CCUserDefault::sharedUserDefault();
	if (ud->isXMLFileExist())
		level = ud->getIntegerForKey("level");
	else
		level = 1;
	loadLevel();
}

void GameScene::loadLevel()
{
	if(g_maze.find(level) == g_maze.end())
		return;

	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

	info = g_maze[level];

	optionShownum = 0;
	curstep = 0;
	qestIdx = 0;
	ispause = true;
	nextStepActionfinished = false;
	for (int i=0; i<info->columns; ++i)
		blankFill.push_back(false);

	optSprites.clear();
	optionPoints.clear();
	blankPoints.clear();
	quesSprites.clear();
	answSprites.clear();

	calculatePoints(level);

	for (int i=0; i<info->steps; ++i)
	{
		vector<string> &qv = info->stepInfo[i];
		for (int j=0; j<8; j++)
		{
			CCSprite *sp = CCSprite::createWithSpriteFrameName(qv[j].c_str());
			sp->setUserData((void*)qv[j].c_str());
			sp->setTag(j);
			sp->setPosition(optPts[j]);
			sp->setVisible(false);
			addChild(sp);

			if(i==0)
				sp->runAction(CCSequence::create(CCDelayTime::create(1.0f * j / 4), 
					CCCallFuncND::create(this,callfuncND_selector(GameScene::displayOneOption), sp), NULL));
			
			optSprites[i].push_back(sp);
		}
	}

	for (int i=0; i<info->columns; ++i)
	{
		CCSprite *sp = CCSprite::createWithSpriteFrameName("border.png");
		sp->setPosition(ansPts[i]);

		CCSprite * sp2 = CCSprite::createWithSpriteFrameName(info->questions[i].c_str());
		sp2->setPosition(quesPts[i]);
		addChild(sp2);
		quesSprites.push_back(sp2);
	}
}

void GameScene::calculatePoints(int l)
{
	quesPts.clear();
	optPts.clear();
	ansPts.clear();

	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
	MazeInfo *mi = g_maze[l];

	for (int i=1; i<=OPT_NUM; ++i)
	{
		int x = 0, y = 0;
		if(i<=OPT_NUM/2) { 
			x = 40 + 80 * (i-1); //visibleSize.width / (OPT_NUM/2+1) * i;
			y = 50;
		}
		else {
			x = 40 + 80 * (i-5);//visibleSize.width / (OPT_NUM/2+1) * (i - OPT_NUM/2);
			y = 140;
		}
		optPts.push_back(ccp(x, y));
	}

	int x=0, y=0;
	int t = mi->columns;
	for (int i=0; i < t; ++i)
	{
		if(t % 2 == 0) {
			if(i < t/2)
				x = visibleSize.width/2 - 100 * (t/2 - i - 1) - 50;
			else
				x = visibleSize.width/2 + 100 * (i - t/2) + 50;
		}
		else {
			if(i < t/2)
				x = visibleSize.width/2 - 100 * (t/2 - i );
			else
				x = visibleSize.width/2 + 100 * (i - t/2 );
		}
		quesPts.push_back(ccp(x, 320));
		ansPts.push_back(ccp(x, 220));
	}
}

void GameScene::displayOneOption(CCNode* pTarget, void* data)
{
	CCSprite *sp = (CCSprite*)pTarget;
	sp->setVisible(true);
	CCActionInterval *act = CCScaleTo::create(0.2f, 1.5f);
	CCActionInterval *act2 = CCScaleTo::create(0.2f, 1.0f);
	sp->runAction(CCSequence::create(act, act2, NULL));
	optionShownum += 1;
	if(optionShownum == 8)
	{
		ispause = false;
		optionShownum = 0;
	}
}

void GameScene::displayOptions()
{
	ispause = true;
	vector<CCSprite* > &vec = optSprites[curstep];
	for (int i=0; i<vec.size(); i++)
	{
		vec[i]->setPosition(optPts[i]);
		vec[i]->runAction(CCSequence::create(CCDelayTime::create(i * optionShowdelay), 
			CCCallFuncND::create(this,callfuncND_selector(GameScene::displayOneOption), vec[i]), NULL));
	}
}

string getName(string s)
{
	int k = s.find('.');
	if(k==-1) return "";
	string a = s.substr(0, k);
	string name;
	int m = a.rfind("_");
	if (m != -1 && m == a.length() - 2)
		name = a.substr(0, m);
	else
		name = a;
	return name;
}

bool GameScene::isRightAnswer(int qidx, int curstep, CCSprite *sp)
{
	char *str = (char *)sp->getUserData();
	string s = info->questions[qidx];
	string qname = getName(s);
	string oname = getName(str);

	if(qname.compare(oname) == 0)
		return true;
	return false;
}

bool GameScene::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
	if(ispause)
		return true;
	CCPoint touchPoint = touch->getLocationInView();  
	touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);
	
	for (int i=0; i<8; i++)
	{
		CCSprite *sp = optSprites[curstep][i];
		CCRect rect = CCRectMake(sp->getPositionX() - sp->getContentSize().width/2, sp->getPositionY() - sp->getContentSize().height/2,
								sp->getContentSize().width, sp->getContentSize().height);
		if (rect.containsPoint(touchPoint) && !isFillBlank())
		{
			if(isRightAnswer(qestIdx, curstep, sp))
			{
				blankFill[qestIdx] = true;
				sp->setPosition(ansPts[qestIdx]);

				answSprites.push_back(sp);
				qestIdx++;
				if (qestIdx == info->columns)
					nextStep();
				break;
			}
			else
			{
				ispause = true;
				sp->setPosition(ansPts[qestIdx]);
				wrongBorderSp->setPosition(ansPts[qestIdx]);

				CCFiniteTimeAction*  action1 = CCSequence::create(CCBlink::create(1, 2),  
					CCCallFuncND::create(this,callfuncND_selector(GameScene::wrongBorderBlinkFinished), sp), NULL);
				 wrongBorderSp->runAction(action1);
			}
		}
	}

	return true;
}

void GameScene::nextStep()
{
	ispause = true;
	nextStepActionfinished = false;

	if (curstep == info->steps - 1)
	{
		#ifdef IOS 
			[self performSelector:@selector(nextLevel) withObject:nil afterDelay:1.0f];
		#else
			nextLevel();
		#endif
		
		return;
	}

	for (int i=0; i<quesSprites.size(); i++)
	{
		CCSprite *sp = quesSprites[i];
		CCPoint pt = ccpAdd(sp->getPosition(), ccp(0, 100));

		CCFiniteTimeAction*  action1 = CCSequence::create(CCMoveTo::create(1, pt),  
			CCCallFuncND::create(this,callfuncND_selector(GameScene::nextStepActionFinished), sp), NULL);
		sp->runAction(action1);
	}
	for (int i=0; i<answSprites.size(); i++)
	{
		CCSprite *sp = answSprites[i];
		CCPoint pt = ccpAdd(sp->getPosition(), ccp(0, 100));

		CCFiniteTimeAction*  action1 = CCSequence::create(CCMoveTo::create(1, pt),  
			CCCallFuncND::create(this,callfuncND_selector(GameScene::nextStepActionFinished), sp), NULL);
		sp->runAction(action1);
	}

	vector<CCSprite* > &vec = optSprites[curstep];
	for (int i=0; i<vec.size(); i++)
	{
		if (find(answSprites.begin(), answSprites.end(), vec[i]) == answSprites.end())
		{
			CCSprite *sp = vec[i];
			sp->setVisible(false);
		}
	}
	qestIdx = 0;
	curstep += 1;

	for (int i=0; i<info->columns; ++i)
		blankFill[i] = false;
}

void GameScene::nextLevel()
{
	level += 1;
	CCUserDefault *save=CCUserDefault::sharedUserDefault();
	save->setIntegerForKey("level", level);
	save->flush();
	CCLog("user default path:%s", save->getXMLFilePath().c_str());

	for (int i=0; i<quesSprites.size(); i++)
	{
		removeChild(quesSprites[i]);
	}
	map<int, vector<CCSprite* > >::iterator it = optSprites.begin();
	for (; it!=optSprites.end(); ++it)
	{
		vector<CCSprite* > &vec = it->second;
		for (int i=0; i<vec.size(); ++i)
		{
			removeChild(vec[i]);
		}
	}

	CCScene *scene = CCScene::create();
	ShareLayer *layer = new ShareLayer;
	layer->level = level;
	layer->init();
	scene->addChild(layer);
	layer->autorelease();
	CCDirector::sharedDirector()->pushScene(scene);
}

void GameScene::ccTouchMoved(CCTouch* touch, CCEvent* event)
{

}

void GameScene::ccTouchEnded(CCTouch* touch, CCEvent* event)
{

}

void GameScene::returnMainMenu(CCObject* pSender)
{
	CCDirector::sharedDirector()->popScene();
}

bool GameScene::isFillBlank()
{
	for (int i=0; i<blankFill.size(); ++i)
	{
		if(!blankFill[i])
			return false;
	}
	return true;
}

int GameScene::getValidBlank()
{
	for (int i=0; i<blankFill.size(); ++i)
	{
		if(!blankFill[i])
			return i;
	}
	return -1;
}

void GameScene::wrongBorderBlinkFinished(CCNode* pTarget, void* data)
{
	wrongBorderSp->setPosition(ccp(-500, -500));
	CCNode *sp = (CCNode *)data;
	int i = sp->getTag();

	CCFiniteTimeAction*  action1 = CCSequence::create(CCMoveTo::create(0.5, optPts[i]),  
		CCCallFuncND::create(this,callfuncND_selector(GameScene::wrongOptionReturnFinished), sp), NULL);

	sp->runAction(action1);
}

void GameScene::wrongOptionReturnFinished(CCNode* pTarget, void* data)
{
	ispause = false;
}

void GameScene::nextStepActionFinished(CCNode* pTarget, void* data)
{
	if(!nextStepActionfinished)
	{
		displayOptions();
		nextStepActionfinished = true;
	}
}
